package com.mogu_soup.map;

import com.mogu_soup.entity.Bomb;
import com.mogu_soup.entity.Bullet;
import com.mogu_soup.entity.Entity;
import com.mogu_soup.entity.Tank;
import com.mogu_soup.game.GameFrame;
import com.mogu_soup.game.LevelInfo;
import com.mogu_soup.util.*;

import java.awt.*;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Map;
import java.util.Properties;
import java.util.Vector;

/**
 * Version: 2.1
 * Author: TangJun
 * Date: 2024-08-03
 * Note:
 */
public class GameMap{

    //地图默认属性
    private static final int MAP_X = Brick.DEFAULT_SIZE;
    private static final int MAP_Y = 4 * Brick.DEFAULT_SIZE + Brick.DEFAULT_SIZE + GameFrame.titleHeight;
    private static final int MAP_WIDTH = Constant.FRAME_HEIGHT ;
    private static final int MAP_HEIGHT = Constant.FRAME_HEIGHT - 5 * Brick.DEFAULT_SIZE;

    private Vector<Brick> bricks;//砖块
    private Vector<Bomb> bombs;//爆炸对象
    private Home home;//基地

    public GameMap() {
        bricks = new Vector<Brick>();
        bombs = new Vector<Bomb>();
        initMap(GameFrame.level);
    }

    //初始化地图
    private void initMap(int level) {
        home = new Home();//生成基地
        //基地周围生成保护砖块
        addRow(home.getX() - Brick.DEFAULT_SIZE*2, home.getY() - Brick.DEFAULT_SIZE,
                home.getX() + Brick.DEFAULT_SIZE*3, Brick.IMAGE_BRICK, 0);
        addCol(home.getX() - Brick.DEFAULT_SIZE*2, home.getY(),
                home.getY() + Brick.DEFAULT_SIZE*2, Brick.IMAGE_BRICK, 0);
        addCol(home.getX() + Brick.DEFAULT_SIZE*2, home.getY(),
                home.getY() + Brick.DEFAULT_SIZE*2, Brick.IMAGE_BRICK, 0);


        //绘制地图
        loadLevel(level);
/*        for (int i = 0; i < 2; i++) {
            addRow(MAP_X, MAP_Y + (i + 2) * Brick.DEFAULT_SIZE,
                    MAP_WIDTH, Brick.IMAGE_BRICK, 0);
        }
        for (int i = 0; i < 3; i++) {
            addRow(MAP_X+Brick.DEFAULT_SIZE,MAP_Y + (i + 6) * Brick.DEFAULT_SIZE,
                    MAP_WIDTH, Brick.IMAGE_GRASS, Brick.DEFAULT_SIZE*2);
        }

        addRow(MAP_X, MAP_Y+ 15 * Brick.DEFAULT_SIZE, 10, Brick.IMAGE_WATER);
        addRow(MAP_WIDTH - 10*Brick.DEFAULT_SIZE, MAP_Y + 15 * Brick.DEFAULT_SIZE, 10, Brick.IMAGE_WATER);

        addRow(MAP_X + 12 * Brick.DEFAULT_SIZE, MAP_Y + 18 * Brick.DEFAULT_SIZE, 5, Brick.IMAGE_STEEL);*/



    }

    //加载关卡信息
    private void loadLevel(int level) {
        LevelInfo levelInfo = LevelInfo.getInstance();
        Properties prop = new Properties();
        try {
            //加载数据
            prop.load(new FileInputStream("level/level" + level));
            int enemyNum = Integer.parseInt(prop.getProperty("enemyNum"));
            String method = prop.getProperty("method");
            int invokeCount = Integer.parseInt(prop.getProperty("invokeCount"));
            String[] pars = new String[invokeCount];
            for (int i = 0; i < invokeCount; i++) {
                pars[i] = prop.getProperty("par" + i);
            }
            //使用数据
            levelInfo.setLevel(level);
            levelInfo.setEnemyNum(enemyNum);
            invokeMethod(method, pars);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    //调用对应方法加载地图
    private void invokeMethod(String name, String[] pars) {
        for (String par : pars) {
            //分割参数
            String[] split = par.split(",");
            int[] arr = new int[split.length];
            for (int i = 0; i < arr.length; i++) {
                arr[i] = Integer.parseInt(split[i]);
            }
            final int dis = Brick.DEFAULT_SIZE;//每个地图块间隔
            if (name.equals("addRow")) {
                if (arr.length == 5) {
                    addRow(MAP_X + arr[0]*dis, MAP_Y + arr[1]*dis,
                            MAP_WIDTH-arr[2]*dis, arr[3], arr[4]*dis);
                } else if (arr.length == 4) {
                    addRow(MAP_X + arr[0]*dis, MAP_Y + arr[1]*dis,
                            arr[2], arr[3]);
                }
            } else if (name.equals("addCol")) {
                addCol(MAP_X + arr[0]*dis, MAP_Y + arr[1]*dis,
                        MAP_HEIGHT-arr[2]*dis, arr[3], arr[4]);
            }
        }
    }

    //生成一行砖块
    private void addRow(int startX, int startY, int endX, int type, int dis) {
        int count = (endX - startX) / (Brick.DEFAULT_SIZE + dis);
        for (int i = 0; i < count; i++) {
            Brick brick = BrickPool.removeBrick();
            brick.set(startX + i * (Brick.DEFAULT_SIZE +dis) , startY, type);
            bricks.add(brick);
        }
    }
    private void addRow(int startX, int startY, int num, int type) {
        for (int i = 0; i < num; i++) {
            Brick brick = BrickPool.removeBrick();
            brick.set(startX + i * (Brick.DEFAULT_SIZE) , startY, type);
            bricks.add(brick);
        }
    }

    //生成一列砖块
    private void addCol(int startX, int startY, int endY, int type, int dis) {
        int count = (endY - startY) / (Brick.DEFAULT_SIZE + dis);
        for (int i = 0; i < count; i++) {
            Brick brick = BrickPool.removeBrick();
            brick.set(startX, startY + i * (Brick.DEFAULT_SIZE +dis), type);
            bricks.add(brick);
        }
    }

    //清空地图
    public void ReturnMap() {
        for (Brick brick : bricks) {
            BrickPool.addBrick(brick);
        }
        for (Bomb bomb : bombs) {
            BombPool.addBomb(bomb);
        }
        bricks.clear();
        bombs.clear();
    }

    //绘制地图
    public void draw(Graphics g) {
        drawHome(g);//绘制基地
        drawBricks(g);//绘制砖块
        drawBombs(g);//绘制爆炸效果
    }

    public void drawCover(Graphics g) {
        for (int i = 0; i < bricks.size(); i++) {

            Brick brick = bricks.get(i);
            if (brick.getType() != Brick.IMAGE_GRASS) {
                continue;
            }
            if (brick.isLive()) {
                brick.draw(g);//绘制存活的砖块
            } else {
                BrickPool.addBrick(bricks.remove(i));//移除销毁的砖块
                i--;
            }
        }
    }
    //绘制砖块
    private void drawBricks(Graphics g) {
        for (int i = 0; i < bricks.size(); i++) {
            Brick brick = bricks.get(i);
            //草块后绘画
            if (brick.getType() == Brick.IMAGE_GRASS) {
                continue;
            }
            if (brick.isLive()) {
                brick.draw(g);//绘制存活的砖块
            } else {
                BrickPool.addBrick(bricks.remove(i));//移除销毁的砖块
                i--;
            }
        }
    }
    //绘制基地
    private void drawHome(Graphics g) {
        if (home.isLive()) {
            home.draw(g);
        } else {
            GameFrame.setGameState(Constant.STATE_OVER);
        }
    }
    //绘制爆炸效果
    private void drawBombs(Graphics g) {
        for (int i = 0; i < bombs.size(); i++) {
            Bomb bomb = bombs.get(i);
            if (bomb.isLive()) {
                bomb.draw(g);//绘制未播放完的爆炸效果
            } else {
                BombPool.addBomb(bombs.remove(i));//移除已播放完的爆炸效果
                i--;
            }
        }
    }

    //判断所有砖块和子弹碰撞
    public void bulletsCollideAll(Vector<Bullet> bullets) {
        for (Brick brick : bricks) {
            bulletsCollide(brick, bullets);
        }
        bulletsCollide(home, bullets);
    }
    //判断单个砖块和子弹碰撞
    public void bulletsCollide(Brick brick, Vector<Bullet> bullets) {
        int type = brick.getType();
        //草块和水块无碰撞
        if (type == Brick.IMAGE_GRASS || type == Brick.IMAGE_WATER) {
            return;
        }
        for (Bullet bullet : bullets) {
            if (Entity.isCollideEntity(brick.getX(), brick.getY(), brick.getSize(),
                                        bullet.getX(), bullet.getY(), bullet.getSize(), bullet.getDir())) {
                bullet.setLive(false);//子弹消失
                //砖块受到攻击
                if (brick.hpDown() <= 0) {
                    brick.setLive(false);
                }
                //产生爆炸效果
                Bomb bomb = BombPool.removeBomb();
                bomb.set(brick.getX(), brick.getY(), brick.getSize());
                bombs.add(bomb);
            }
        }
    }

    public Vector<Brick> getBricks() {
        return bricks;
    }
}
